﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using Sistema_Totem.Logica.Excepciones;
using Sistema_Totem.Logica.Clases;

namespace Sistema_Totem.Datos.SqlServer
{
    public class SqlServerActor
    {


        #region Agregar Actor

        /// <summary>
        /// Registra el Actor nuevo en la Base de datos 
        /// </summary>
        /// <param name="actor">Recibe un objeto del tipo actor</param>
        /// <param name="idProyecto">Recibe el id del proyecto actual</param>
        /// <returns>Int de confirmacion sobre la transaccion</returns>
        public int AgregarActor(Actor actor, string idProyecto)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("idProyecto");
            variables.Add("nombreActor");
            variables.Add("descripcionActor");
            variables.Add("estatusActor");
            valores.Add(idProyecto);
            valores.Add(actor.Nombre);
            valores.Add(actor.Descripcion);
            valores.Add(actor.Estatus);
           
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[InsertarActor]", variables, valores);

            return resultado;

        }

        #endregion Agregar Actor

        #region Cambiar Estatus Actor
        /// <summary>
        /// Metodo que cambia el estatus de un actor
        /// </summary>
        /// <param name="actor">Recibe un objeto del tipo actor</param>
        /// <param name="estatusNuevo">Recibe el string con el estatus nuevo para el actor</param>
        /// <returns>Int de confirmacion sobre la transaccion</returns>
        public int CambiarEstatusActor(Actor actor, string estatusNuevo)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("idActor");
            variables.Add("estatusNuevo");
            valores.Add(actor.IdActor.ToString());
            valores.Add(estatusNuevo);

            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[CambiarEstatusActor]", variables, valores);

            return resultado;

        }

        #endregion Cambiar Estatus Actor

        #region Consultar Actor por Proyecto
        /// <summary>
        /// Metodo que devuelve los actores asociados al proyecto actual
        /// </summary>
        /// <param name="idProyecto">Recibe el id del proyecto actual</param>
        /// <returns>retorna una lista de actores, con todos los actores asociados al proyecto</returns>
        public List<Actor> ConsultarActor(int idProyecto)
        {
            List<String> variables = new List <String>();
            List<String> valores = new List <String>();
            List<Actor> actores = new List <Actor>();

            variables.Add("idProyecto");
            valores.Add(idProyecto.ToString());
            Conexion conexion = new Conexion();
            try
            {
                SqlDataReader reader = BuscarData(conexion, "[dbo].[ConsultarActor]", variables, valores);

                while (reader.Read())
                {

                    Actor actor = new Actor(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(1), reader.GetString(2), reader.GetString(3));
                    actores.Add(actor);
                }

                return actores;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();
            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {
                conexion.CerrarConexionBd();
            }
        }

        #endregion Consultar Actor por Proyecto

        #region Consultar Detalle Actor
        /// <summary>
        /// Metodo que consulta la informacion del actor particular 
        /// </summary>
        /// <param name="idActor">Recibe el id del actor que desea ser consultado</param>
        /// <returns>retorna un objeto actor con toda la informacion requerida</returns>
        public Actor ConsultarDetalleActor(int idActor)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            Actor actor = null;
            
            variables.Add("idActor");
            valores.Add(idActor.ToString());
            Conexion conexion = new Conexion();
            try
            {
                SqlDataReader reader = BuscarData(conexion, "[dbo].[ConsultarDetalleActor]", variables, valores);

                while (reader.Read())
                {
                    actor = new Actor(idActor, reader.GetString(0), reader.GetString(1), reader.GetString(2));
                }
                return actor;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                conexion.CerrarConexionBd();
            }
        }

        #endregion Consultar Detalle Actor

        #region Consultar Actor por Caso de Uso
        /// <summary>
        /// Metodo que devuelve los actores asociados al caso de uso
        /// </summary>
        /// <param name="idCasoDeUso">Recibe el id del caso de uso</param>
        /// <returns>retorna una lista de actores, con todos los actores asociados al caso de uso</returns>
        public List<Actor> ConsultarActorCasoDeUso(int idCasoDeUso)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<Actor> actores = new List<Actor>();
            variables.Add("idCasoDeUso");
            valores.Add(idCasoDeUso.ToString());

            Conexion conexion = new Conexion();
            try
            {
                SqlDataReader reader = BuscarData(conexion, "[dbo].[ConsultarActorCasoDeUso]", variables, valores);
                while (reader.Read())
                {

                    Actor actor = new Actor(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(1));
                    actores.Add(actor);
                }

                return actores;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                conexion.CerrarConexionBd();
            }
        }

        #endregion Consultar Actor por Caso de Uso

        #region Asignar Actor a Caso de Uso

        /// <summary>
        /// Metodo que asigna un actor a un caso de uso
        /// </summary>
        /// <param name="isActor">Recibe el id del actor</param>
        /// <param name="idCasoDeUso">Recibe el id del caso de uso</param>
        /// <returns>Int de confirmacion de la transaccion</returns>
        public int AsignarActor(int idActor, string idCasodeUso)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("idActor");
            variables.Add("idCasodeUso");
            valores.Add(idActor.ToString());
            valores.Add(idCasodeUso);
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[AsignarActor]", variables, valores);

            return resultado;

        }

        #endregion Asignar Actor

        #region Quitar Actor Caso De Uso

        /// <summary>
        /// Metodo que des-asigna un actor a un caso de uso
        /// </summary>
        /// <param name="isActor">Recibe el id del actor</param>
        /// <param name="idCasoDeUso">Recibe el id del caso de uso</param>
        /// <returns>Int de confirmacion de la transaccion</returns>
        public int QuitarActorCasoDeUso(int idActor, string idCasodeUso)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("idActor");
            variables.Add("idCasodeUso");
            valores.Add(idActor.ToString());
            valores.Add(idCasodeUso);
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[QuitarActorCasoDeUso]", variables, valores);


            return resultado;

        }

        #endregion Quitar Actor Caso De Uso

        #region Editar Actor

        /// <summary>
        /// Registra todos los cambios hechos en la informacion del actor
        /// </summary>
        /// <param name="actor">Se recibe el objeto actor con los datos nuevos</param>
        /// <param name="idActorViejo">Se recibe el id del actor al que hay que modificar</param>
        /// <returns>Int de confirmacion sobre la transaccion </returns>
        public int EditarActor(Actor actor, int idActorViejo)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("idActor");
            variables.Add("nombreActor");
            variables.Add("descripcionActor");
            variables.Add("estatusActor");
            valores.Add(idActorViejo.ToString());
            valores.Add(actor.Nombre);
            valores.Add(actor.Descripcion);
            valores.Add(actor.Estatus);
           
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[ModificarActor]", variables, valores);

           
            return resultado;

        }

        #endregion Editar Actor

        #region Eliminar Actor

        /// <summary>
        /// Elimina un actor
        /// </summary>
        /// <param name="idActor">Se recibe el id del actor al que hay que eliminar</param>
        /// <returns>Int de confirmacion sobre la transaccion </returns>
        public int EliminarActor(int idActor)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("idActor");
            valores.Add(idActor.ToString());
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[EliminarActor]", variables, valores);


            return resultado;

        }

        #endregion Eliminar Actor

        #region Obtener Ultimo Actor

        /// <summary>
        /// Devuelve el id con el que hay que insertar el siguiente actor
        /// </summary>
        /// <returns>Int con el id proximo</returns>
        public int ObtenerUltimoActor()
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            
            Conexion conexion = new Conexion();
            int id = 0;
            try
            {
                SqlDataReader reader = BuscarData(conexion, "[dbo].[ObtenerIdActor]", variables, valores);
                if (reader.Read())
                {
                    id = Convert.ToInt32(reader.GetDecimal(0)) + 1;
                }
                else
                {
                    id = 0;
                }
                return id;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                conexion.CerrarConexionBd();
            }
        }

        #endregion Obtener Ultimo Actor

        #region Obtener Id Proyecto

        /// <summary>
        /// Consultar que proyecto es el actua;
        /// </summary>
        /// <param name="nombreProyecto">Nombre del proyecto actual</param>
        /// <returns>Int con el id</returns>
        public int ObtenerIdProyecto(string nombreProyecto)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("nombre");
            valores.Add("TOTEM");
            Conexion conexion = new Conexion();
            try
            {
                SqlDataReader reader = BuscarData(conexion, "[dbo].[ProyectoActual]", variables, valores);
                int resultado = 0;
                if (reader.Read())
                {
                    //System.Diagnostics.Debug.Write(reader.GetValue(0));
                    //System.Diagnostics.Debug.Write(reader.GetDataTypeName(0));
                    resultado = Convert.ToInt32(reader.GetDecimal(0));
                }
                else
                {
                    resultado = 0;
                }

                return resultado;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                conexion.CerrarConexionBd();
            }
        }

        #endregion Obtener Id Proyecto

        #region Buscar Data

        /// <summary>
        /// Metodo encargado de invocar a los stored
        /// procedures para realizar transacciones de
        /// consulta.
        /// Devuelve SqlDataReader si se realizo la operacion
        /// efectivamente.
        /// Los metodos que invoquen a este metodo deben cerrar
        /// la conexion luego de leer la data, ya que si se cierra
        /// aqui no se puede ejecutar el reader.
        /// </summary>

        public SqlDataReader BuscarData(Conexion conexion, String nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {


            SqlCommand comando = new SqlCommand();
            SqlDataReader lector = null;

            try
            {
                //se abre una conexion a base de datos
                conexion.AbrirConexionBd();
                //se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;
                //variables del stored procedure de sql server
                int i = 0;
                while (i < variablesProcedure.Count())
                {

                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;

                    i++;
                }
                //se ejecuta el comando
                lector = comando.ExecuteReader();
                return lector;

            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }

            

        }


        #endregion Buscar Data

        #region Ejecutar Query

        /// <summary>
        /// Metodo encargado de invocar a los stored
        /// procedures para realizar transacciones de
        /// insercion,modificacion y eliminacion.
        /// Devuelve int 1 si se realizo la operacion
        /// efectivamente.
        /// </summary>

        public int EjecutarQuery(Conexion conexion, String nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {


            SqlCommand comando = new SqlCommand();

            try
            {
                //se abre una conexion a base de datos
                conexion.AbrirConexionBd();
               //se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;
                 //variables del stored procedure de sql server
                 int i = 0;
                 while (i < variablesProcedure.Count())
                 {

                     comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                     comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;

                     i++;
                 }
                
                comando.ExecuteScalar();
                return 1;
            }

            catch (ErrorConexionException S)
            {
                Console.WriteLine(S.MensajeError());
                return -1;
            }
           
            catch (Exception E)
            {
                Console.WriteLine(E.Message);
                return -2;
            }

            finally
            {
                conexion.CerrarConexionBd();

            }
        }


        #endregion Ejecutar Query


    }
}